package com.ruoyi.pcj.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.mashuai.utils.base.MsAssertUtils;
import com.mashuai.utils.base.MsEmptyUtils;
import com.mashuai.utils.toolkit.core.msConverts.MsStreamUtils;
import com.mashuai.utils.toolkit.core.msConverts.MsTimeUtils;
import com.mashuai.utils.toolkit.core.msHandlebean.MsHandleDataUtils;
import com.ruoyi.basis.service.MsBaseServiceImpl;

import java.util.List;

import com.mashuai.utils.toolkit.core.msMp.MsDb;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.basis.utils.mp.MpConditionUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.pcj.domain.PcjLtFriendList;
import com.ruoyi.pcj.domain.PcjLtFriendRecords;
import com.ruoyi.pcj.dto.friend.FriendListDto;
import com.ruoyi.pcj.dto.friend.FriendNewMsgDto;
import com.ruoyi.pcj.dto.friend.FriendSessionDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;

import com.ruoyi.pcj.mapper.PcjLtFriendSettingMapper;
import com.ruoyi.pcj.domain.PcjLtFriendSetting;
import com.ruoyi.pcj.service.IPcjLtFriendSettingService;

import java.util.Map;

import com.ruoyi.basis.utils.mp.MpPageUtils;
import org.springframework.transaction.annotation.Transactional;

/**
 * 聊天-好友列信息设置Service业务层处理
 *
 * @author ms
 * @date 2024-03-28
 */
@Service
public class PcjLtFriendSettingServiceImpl extends MsBaseServiceImpl<PcjLtFriendSettingMapper, PcjLtFriendSetting> implements IPcjLtFriendSettingService {

    @Override
    public <E extends IPage<PcjLtFriendSetting>> E page(E page, Wrapper<PcjLtFriendSetting> qw) {
        return baseMapper.selectPage(page, qw);
    }

    /**
     * 查询聊天-好友列信息设置列表
     *
     * @param params 聊天室-查询参数 {"pageNum":1,"pageSize":10}
     * @return 聊天-好友列信息设置
     */
    @Override
    public IPage<PcjLtFriendSetting> selectPcjLtFriendSettingList(Map<String, Object> params) {
        //获取条件构造器
        QueryWrapper<PcjLtFriendSetting> qw = MpConditionUtils.getQueryWrapper(params, PcjLtFriendSetting.class);
        //分页查询
        Page<PcjLtFriendSetting> page = this.page(MpPageUtils.getPage(params), qw);
        return page;
    }


    /**
     * 根据id查询聊天-好友列信息设置
     *
     * @param id 聊天-好友列信息设置主键
     * @return 聊天-好友列信息设置
     */
    @Override
    public PcjLtFriendSetting selectPcjLtFriendSettingById(String id) {
        //首先获取主表信息
        PcjLtFriendSetting pcjLtFriendSetting = MsDb.getById(id, PcjLtFriendSetting.class);
        return pcjLtFriendSetting;
    }

    /**
     * 回填子表信息
     **/

    /**
     * 新增聊天-好友列信息设置
     *
     * @param pcjLtFriendSetting 聊天-好友列信息设置
     * @return 结果
     */
    @Override
    public Boolean insertPcjLtFriendSetting(PcjLtFriendSetting pcjLtFriendSetting) {
        //插入主表
        Boolean success = this.insertData(pcjLtFriendSetting);
        return success;
    }

    /**
     * 修改聊天-好友列信息设置
     *
     * @param pcjLtFriendSetting 聊天-好友列信息设置
     * @return 结果
     */
    @Override
    public Boolean updatePcjLtFriendSetting(PcjLtFriendSetting pcjLtFriendSetting) {
        //修改主表
        Boolean success = this.updateData(pcjLtFriendSetting);
        return success;
    }

    /**
     * 批量删除聊天-好友列信息设置
     *
     * @param ids 需要删除的聊天-好友列信息设置主键
     * @return 结果
     */
    @Override
    public Boolean deletePcjLtFriendSettingByIds(String[] ids) {

        //删除主表
        Boolean success = this.removeBatchByIds(Arrays.asList(ids));
        return success;
    }
    /**
     * 根据主表id，删除子表所有数据
     **/
    /**
     * 对外提供的设置默认字段值，id为空新增，不为空更新
     **/
    @Override
    public void setEntityDefValAuto(PcjLtFriendSetting pcjLtFriendSetting) {
        this.setDefFieldVal(pcjLtFriendSetting);
    }

    /**
     * 获取指定用户和好友id设置信息，只可有一条数据
     **/
    @Override
    public List<PcjLtFriendSetting> getFriendSettingData(Long userId, Long friendId) {
        MsAssertUtils.objIsNulls(userId, friendId);
        LambdaQueryWrapper<PcjLtFriendSetting> qw = Wrappers.lambdaQuery();
        qw.eq(PcjLtFriendSetting::getUserId, userId);
        qw.eq(PcjLtFriendSetting::getFriendId, friendId);
        List<PcjLtFriendSetting> friendSettingList = MsDb.list(qw, PcjLtFriendSetting.class);
        return friendSettingList;
    }

    @Override
    public PcjLtFriendSetting initFriendSettingMsg(Long userId, Long friendId) {
        List<PcjLtFriendSetting> friendSettingList = getFriendSettingData(userId, friendId);
        //如果没有好友设置，则新增两条
        if (friendSettingList.size() == 0) {
            return addFriendSetting(userId, friendId);
        }
        //理论上来说，userId+friendId确定唯一一条信息
        if (friendSettingList.size() > 1) {
            MsAssertUtils.throwException("出现重复好友信息，请联系管理员！");
        }
        return friendSettingList.get(0);
    }


    /**
     * 新增两条好友设置信息
     **/
    private PcjLtFriendSetting addFriendSetting(Long userId, Long friendId) {
        PcjLtFriendSetting entity = new PcjLtFriendSetting();
        entity.setUserId(userId);
        entity.setFriendId(friendId);
        MsHandleDataUtils.handleTbOrDictValBeans(entity, PcjLtFriendSetting.class);
        //设置好友，新增两条,二人是双向关系
        PcjLtFriendSetting ps1 = new PcjLtFriendSetting();
        ps1.setUserId(entity.getUserId());
        ps1.setFriendId(entity.getFriendId());
        ps1.setFriendAlias(entity.getFriendName());
        //默认状态正常、非特别关心，没有聊天会话
        ps1.setStatus("0");
        ps1.setParticularConcern("0");
        ps1.setSessionStatus("0");
        ps1.setSessionSeqNo(0);
        this.insertData(ps1);
        //设置第二个人
        PcjLtFriendSetting ps2 = new PcjLtFriendSetting();
        ps2.setUserId(entity.getFriendId());
        ps2.setFriendId(entity.getUserId());
        ps2.setFriendAlias(entity.getUserName());
        ps2.setStatus("0");
        ps2.setParticularConcern("0");
        ps2.setSessionStatus("0");
        ps2.setSessionSeqNo(0);
        this.insertData(ps2);
        //批量插入
        return ps1;
    }


    @Override
    public List<FriendListDto> getFriendList() {
        Long userId = SecurityUtils.getUserId();
        List<FriendListDto> friendListDtoList = baseMapper.getFriendList(userId);
        return friendListDtoList;
    }

    @Override
    public List<FriendSessionDto> getChatSession() {
        Long userId = SecurityUtils.getUserId();
        //获取会话：好友置顶优先展示，其次是会话的最后聊天时间降序
        List<FriendSessionDto> sessionDtoList = baseMapper.getChatSession(userId);
        if (sessionDtoList.size() != 0) {
            //查询用户未读信息数量，接受人是自己的，发送人是朋友的未读信息
            List<Long> friendIds = MsStreamUtils.listStreamMap(sessionDtoList, FriendSessionDto::getFriendId);
            LambdaQueryWrapper<PcjLtFriendRecords> qw = Wrappers.lambdaQuery();
            qw.eq(PcjLtFriendRecords::getReceiverUserId, userId);
            qw.in(PcjLtFriendRecords::getSendUserId, friendIds);
            qw.eq(PcjLtFriendRecords::getStatus, "0");
            List<PcjLtFriendRecords> list = MsDb.list(qw, PcjLtFriendRecords.class);
            Map<Long, List<PcjLtFriendRecords>> friendRecordMap = MsStreamUtils.groupBy(list, PcjLtFriendRecords::getSendUserId);
            //查询用户最新一条聊天记录
            List<String> msgIds = MsStreamUtils.listStreamMap(sessionDtoList, FriendSessionDto::getNewMsgId);
            List<FriendNewMsgDto> newMsgDtoList = baseMapper.getRecordsByIds(msgIds);
            Map<String, FriendNewMsgDto> msgMap = MsStreamUtils.groupByT(newMsgDtoList, FriendNewMsgDto::getId);
            //处理会话信息
            for (FriendSessionDto dto : sessionDtoList) {
                List<PcjLtFriendRecords> unReadList = friendRecordMap.get(dto.getFriendId());
                if (unReadList != null && unReadList.size() != 0) {
                    dto.setUnreadNum(unReadList.size());
                } else {
                    dto.setUnreadNum(0);
                }
                //处理最新一条聊天信息
                FriendNewMsgDto records = msgMap.get(dto.getNewMsgId());
                if (records != null) {
                    //判断是否自己发送的
                    if (userId != records.getSendUserId()) {
                        String content = records.getContent();
                        String friendName = dto.getFriendName();
                        if (MsEmptyUtils.isNotEmpty(dto.getFriendAlias())) {
                            friendName = dto.getFriendAlias();
                        }
                        records.setContent(friendName + "：" + content);
                    }
                    dto.setNewMsg(records);
                }
            }
        }
        return sessionDtoList;
    }
}
